<?php

namespace Biz\module\Classes\mgt;

use Biz\model\activity\ActivityRegisterGoods as mActivityRegisterGoods;
use Biz\service\Sku as sSku;
use Doraemon\tools\Log;
use Biz\model\SelectGoodsLog as mSelectGoodsLog;
use Biz\pockets\constInterface\ActivityInfo;

class ActiviesRegisterSave
{
    public function save($registerId, $shopId, $discountType, $discountLevel, array $goodsList)
    {
        $registerInfos = mActivityRegisterGoods::getInfos([$registerId], $shopId);

        mActivityRegisterGoods::action(function () use ($registerInfos, $registerId, $shopId, $discountType, $discountLevel, $goodsList) {

            $this->checkPrice($discountType, $goodsList);
            if ($registerInfos) {
                // 曾经报名过
                $this->update($registerInfos, $registerId, $shopId, $discountType, $discountLevel, $goodsList);
            } else {
                // 第一次报名
                $this->insert($registerId, $shopId, $discountType, $discountLevel, $goodsList);

            }
        });
    }

    private function update($registerInfos, $registerId, $shopId, $discountType, $discountLevel, $goodsList)
    {
        $this->check_can_update($registerInfos, $registerId, $shopId, $discountType, $discountLevel, $goodsList);
        mActivityRegisterGoods::saveRegister($registerId, $shopId, $discountLevel, $discountType, $goodsList);
    }

    private function check_can_update($registerInfos, $registerId, $shopId, $discountType, $discountLevel, $goodsList)
    {
        $goodsIds = ($registerInfos && $registerInfos['goods']) ? array_keys($registerInfos['goods']) : [];
        // 查询日志表,查看是否已经有被选中的商品
        $is_has_selected = mSelectGoodsLog::select('goods_id', [
            'register_id' => $registerId,
            'shop_id' => $shopId,
            'status' => mSelectGoodsLog::STATUS_NORMAL,
            'type' => ActivityInfo::ACTIVITY_TYPE_WEEK_PURCHASE
        ]);
        if ($is_has_selected) {
            $selectedGoodsIds = array_flip($is_has_selected);
            foreach ($goodsIds as $goodsId) {
                if (isset($selectedGoodsIds[$goodsId])) {
                    $registerInfos['goods'][$goodsId]['is_selected'] = 1;
                }
            }
        }

        $is_change_discountInfo = false;
        if ($registerInfos[$registerId]['discount_level'] != $discountLevel ||
            $registerInfos[$registerId]['discount_type'] != $discountType
        ) {
            $is_change_discountInfo = true;
        }
        //存在被选中的商品 不允许删除该商品
        $goodsListGrpByGid = array_column($goodsList, null, 'goods_id');
        foreach ($registerInfos[$registerId]['goods'] as $goodsId => $registerInfo) {
            if (isset($registerInfo['is_selected']) && $registerInfo['is_selected'] && !isset($goodsListGrpByGid[$goodsId])) {
                throw new \Exception('被选中的商品 不允许删除');
            }
        }

        if ($is_change_discountInfo) {
            if ($is_has_selected) {
                //商品中是否有被选中的商品 如果有 优惠级别 优惠方式不能更改
                throw new \Exception('存在被选中的商品 优惠级别 优惠方式 不允许修改');
            } else {
                // 若优惠级别 优惠方式被更改 则 清除之前的报名信息
                mActivityRegisterGoods::deleteRegister($registerId, $shopId);
            }
        }

    }

    private function insert($registerId, $shopId, $discountType, $discountLevel, $goodsList)
    {
        mActivityRegisterGoods::saveRegister($registerId, $shopId, $discountLevel, $discountType, $goodsList);
    }

    private function checkPrice($discountType, $goodsList)
    {
        $skuIds = [];
        foreach ($goodsList as $goods) {
            foreach ($goods['skus'] as $skus) {
                if (!(float)$skus['actual_price']) {
                    throw new \Exception('请检查商品ID ' . $goods['goods_id'] . " 价格信息");
                }
            }
            $skuIds = array_merge($skuIds, array_column($goods['skus'], 'sku_id'));
        }
        $skuInfos = $skuIds ? sSku::Sku4Order($skuIds) : [];
        foreach ($goodsList as $goods) {
            foreach ($goods['skus'] as $sku) {
                if (!isset($skuInfos[$sku['sku_id']])) {
                    throw new \Exception('请检查商品ID ' . $goods['goods_id'] . " sku信息是否正确");
                }
            }
        }

        try {
            switch ($discountType) {
                case mActivityRegisterGoods::DISCOUNT_TYPE_DEFAULT :
                    $this->disCount($goodsList, $skuInfos);
                    break;
                case mActivityRegisterGoods::DISCOUNT_TYPE_REDUCE_MONEY :
                    $this->reduceMoney($goodsList, $skuInfos);
                    break;
                case mActivityRegisterGoods::DISCOUNT_TYPE_PROMOTION :
                    $this->promotion($goodsList, $skuInfos);
                    break;
                default:
                    throw new \Exception('优惠类型错误');
            }
        } catch (\Exception $e) {
            Log::debug("价格计算不正确", [
                'e_msg' => $e->getMessage(),
                'e_file' => $e->getFile(),
                'e_line' => $e->getLine()
            ]);
        }
        return true;
    }

    private function disCount($goodsList, $skuInfos)
    {
        foreach ($goodsList as $goods) {
            $is_pick_up = $goods['is_pick_up'];
            foreach ($goods['skus'] as $skus) {
                $actualPrice = $skus['discount_degree'] * $skuInfos[$skus['sku_id']]['ori_price'] / 10;
                $actualPrice = round($actualPrice, 2);
                if ($is_pick_up) {
                    $actualPrice = round($actualPrice);
                }
                if ($actualPrice != $skus['actual_price'] || !$skus['actual_price']) {
                    throw new \Exception('价格计算不正确' . $skus['sku_id'] . "_" . $actualPrice . "_" . $skus['actual_price']);
                }
            }
        }
    }

    private function reduceMoney($goodsList, $skuInfos)
    {
        foreach ($goodsList as $goods) {
            $is_pick_up = $goods['is_pick_up'];
            foreach ($goods['skus'] as $skus) {
                $actualPrice = $skuInfos[$skus['sku_id']]['ori_price'] - $skus['discount_degree'];
                $actualPrice = round($actualPrice, 2);
                if ($is_pick_up) {
                    $actualPrice = round($actualPrice);
                }
                if ($actualPrice != $skus['actual_price'] || !$skus['actual_price']) {
                    throw new \Exception('价格计算不正确' . $skus['sku_id'] . "_" . $actualPrice . "_" . $skus['actual_price']);
                }
            }
        }

    }

    private function promotion($goodsList, $skuInfos)
    {
        foreach ($goodsList as $goods) {
            $is_pick_up = $goods['is_pick_up'];
            foreach ($goods['skus'] as $skus) {
                $actualPrice = $skus['actual_price'];
                $actualPrice = round($actualPrice, 2);
                if ($is_pick_up) {
                    $actualPrice = round($actualPrice);
                }
                if ($actualPrice > $skuInfos[$skus['sku_id']]['ori_price'] || !$skus['actual_price']) {
                    throw new \Exception('价格高于正常售价' . $skus['sku_id'] . "_" . $actualPrice . "_" . $skus['actual_price']);
                }
            }
        }

    }


}